<?php

namespace app\core\auth;

//use app\core\components\GoogleAuthenticator;
use app\core\entities\User;
use app\core\repositories\user\read\UserReadRepository;
use OAuth2\Storage\UserCredentialsInterface;
use Yii;
use yii\base\InvalidConfigException;
use yii\base\Module;
use yii\di\NotInstantiableException;
use yii\filters\RateLimitInterface;
use yii\web\IdentityInterface;

class Identity implements IdentityInterface, UserCredentialsInterface, RateLimitInterface
{
    public User $user;

    public int $rateLimit = 800;
//    public $allowance;
//    public $allowance_updated_at;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * @throws NotInstantiableException
     * @throws InvalidConfigException
     */
    public static function findIdentity($id): ?Identity
    {
        $user = self::getRepository()->findActiveById($id);
        return $user ? new self($user): null;
    }

    /**
     * @throws NotInstantiableException
     * @throws InvalidConfigException
     */
    public static function findIdentityByAccessToken($token, $type = null): User|IdentityInterface|null
    {
        //return self::getRepository()->findByAccessToken($token);
        $data = self::getOauth()->getServer()->getResourceController()->getToken();
        return !empty($data['user_id']) ? static::findIdentity($data['user_id']) : null;
    }

    public function getId(): string
    {
        return $this->user->id;
    }

    public function getAuthKey(): string
    {
        return $this->user->auth_key;
    }

    public function validateAuthKey($authKey): bool
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * @throws NotInstantiableException
     * @throws InvalidConfigException
     */
    public function checkUserCredentials($username, $password): bool
    {
        $factor2 = filter_var(Yii::$app->request->post('factor2'), FILTER_VALIDATE_INT);

        if (!$user = self::getRepository()->findByEmail($username)) {
            return false;
        }

//        if ($user->usedFactor2()) {
//            if (!$factor2) {
//                return false;
//            }
//
//            $ga = new GoogleAuthenticator();
//            $checkResult = $ga->verifyCode($user->factor2_code, $factor2, 2);
//            if (!$checkResult) {
//                return false;
//            }
//        }

        return $user->validatePassword($password);
    }

    /**
     * @param $username
     * @return array
     * @throws InvalidConfigException
     * @throws NotInstantiableException
     */
    public function getUserDetails($username): array
    {
        $user = self::getRepository()->findByEmail($username);
        return ['user_id' => $user->id];
    }

    /**
     * @throws NotInstantiableException
     * @throws InvalidConfigException
     */
    private static function getRepository(): UserReadRepository
    {
        return Yii::$container->get(UserReadRepository::class);
    }

    private static function getOauth(): ?Module
    {
        return Yii::$app->getModule('oauth2');
    }

    public function getRateLimit($request, $action): array
    {
        return [$this->rateLimit, 600];
    }

    public function loadAllowance($request, $action): array
    {
        return [$this->user->allowance, $this->user->allowance_updated_at];
    }

    public function saveAllowance($request, $action, $allowance, $timestamp): void
    {
        $this->user->allowance = $allowance;
        $this->user->allowance_updated_at = $timestamp;
        $this->user->save();
    }
}
